package com.mobilerecognition.phonenumer.ui;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.Vibrator;
import android.support.annotation.Keep;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.ScrollView;
import android.widget.Toast;

import com.mobilerecognition.engine.RecogEngine;
import com.mobilerecognition.engine.RecogResult;
import com.mobilerecognition.phonenumer.R;
import com.mobilerecognition.phonenumer.camera.CameraPreview;
import com.mobilerecognition.phonenumer.camera.ViewfinderView;
import com.mobilerecognition.phonenumer.general.CGlobal;
import com.mobilerecognition.phonenumer.handler.RecogListener;
import com.mobilerecognition.phonenumer.handler.ScanHandler;
import com.mobilerecognition.phonenumer.utils.CameraSetting;
import com.mobilerecognition.phonenumer.utils.SoundClips;
import com.mobilerecognition.phonenumer.utils.Tools;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class ScanerActivity extends Activity implements OnClickListener, RecogListener, SensorEventListener {

    protected static final String TAG = "ScanTestActivity";
    protected CameraPreview mCameraPreview;
    protected RelativeLayout mHomeLayout;
    protected Vibrator vibrator;
    @Keep
    protected ScanHandler m_scanHandler;
    protected PowerManager.WakeLock wakeLock;
    @Keep
    protected boolean isbIsAvailable = true; //是否扫描开关
    @Keep
    protected boolean isQrCodeOne = true; // 首先扫描条形码
    protected long lastResultTime;
    protected long lastSuccessTime;
    protected String lastRecgResultString = null;
    protected SoundClips.Player mSoundPlayer;
    @Keep
    protected SensorManager sensorManager;

    @Keep
    protected ViewfinderView mQrCodeFinderView;

    @Keep
    private RelativeLayout mScanLayout;
    protected RelativeLayout mScanerRootLayout;
    protected ScrollView        mScrollViewContent;
    protected LinearLayout mScanerBottomLayout;
    protected LinearLayout mScanerContentLayout;
    protected RelativeLayout mScanerHandleLayout;

    @SuppressLint("InvalidWakeLockTag")
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scanner);

        if (CGlobal.myEngine == null) {
            CGlobal.myEngine = new RecogEngine();
            CGlobal.myEngine.initEngine();
        }
        if (CGlobal.myEngineOld == null) {
            CGlobal.myEngineOld = new com.recogEngine.RecogEngine();
            CGlobal.myEngineOld.initEngine();
        }
        mHomeLayout = findViewById(R.id.previewLayout);
        mHomeLayout.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCameraPreview != null) {
                    mCameraPreview.autoCameraFocuse();
                }
            }
        });

        mScanLayout = findViewById(R.id.rl_scaner_layout);
        mScanerRootLayout = findViewById(R.id.rl_root);
        mScanerBottomLayout = findViewById(R.id.ll_scaner_bottom);
        mScanerHandleLayout = findViewById(R.id.rl_handle_layout);
        mQrCodeFinderView = findViewById(R.id.detect_scan);
        mScrollViewContent = findViewById(R.id.scrollView_content);
        mScanerContentLayout = findViewById(R.id.ll_content);

        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        wakeLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "WakeLockActivity");

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }


    @Keep
    public RelativeLayout getScanLayout() {
        return mScanLayout;
    }

    @Keep
    public void setContentLayoutAndPadding(View view){
        mScrollViewContent.setVisibility(View.VISIBLE);
        int gap = 1;
        int hei = (int) ((getWindow().getWindowManager().getDefaultDisplay().getWidth() - gap * 2) /1.1 );
        mScrollViewContent.setPadding(0,hei,0,0);
        mScanerContentLayout.addView(view);
    }


    @Keep
    public void showScanerHandleLayout(boolean isShow) {
        mScanLayout.setVisibility(isShow ? View.VISIBLE : View.GONE);
        mScanerBottomLayout.setVisibility(isShow ? View.VISIBLE : View.GONE);
        mScanerHandleLayout.setVisibility(!isShow ? View.VISIBLE : View.GONE);
    }

    @Keep
    public void addView2Root(View topView) {
        mScanerRootLayout.addView(topView);
    }

    @Keep
    public void setTopMargin(int topMargin) {
        RelativeLayout.LayoutParams scanLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        scanLayoutParams.topMargin = Tools.dip2px(getApplicationContext(), topMargin);
        mScanLayout.setLayoutParams(scanLayoutParams);
        mScanerHandleLayout.setLayoutParams(scanLayoutParams);
    }

    @Keep
    public void openFlash(boolean isOpen) {
        if (mCameraPreview != null && mCameraPreview.mCamera != null) {
            if (isOpen == false) {
                CameraSetting.getInstance(this).openCameraFlash(mCameraPreview.mCamera);
            } else {
                CameraSetting.getInstance(this).closedCameraFlash(mCameraPreview.mCamera);
            }
        }

    }

    @Keep
    public void setTopMarginPx(int topMargin) {
        RelativeLayout.LayoutParams scanLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        scanLayoutParams.topMargin = topMargin;
        mScanLayout.setLayoutParams(scanLayoutParams);
        mScanerHandleLayout.setLayoutParams(scanLayoutParams);
    }

    @Keep
    public void addView2BottomLayout(View view) {
        mScanerBottomLayout.addView(view);
    }

    @Keep
    public void addView2BottomLayout(View view, int index) {
        mScanerBottomLayout.addView(view, index);
    }


    @Keep
    public void addView2ScanerHandle(View topView) {
        mScanerHandleLayout.addView(topView);
    }

    @Keep
    public Handler getHandler() {
        return m_scanHandler;
    }

    @Override
    protected void onResume() {
        super.onResume();
        mCameraPreview = new CameraPreview(this, 0, CameraPreview.LayoutMode.FitToParent);
        LayoutParams previewLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mHomeLayout.addView(mCameraPreview, 0, previewLayoutParams);
        if (m_scanHandler == null) {
            m_scanHandler = new ScanHandler(this, mCameraPreview);
        }
        m_scanHandler.sendEmptyMessageDelayed(R.id.auto_focus, 1000);

        if (wakeLock != null) wakeLock.acquire();
        sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mCameraPreview.cancelAutoFocus();
        if (m_scanHandler != null) {
            m_scanHandler.quitSynchronously();
            m_scanHandler = null;
        }

        mCameraPreview.stop();
        mHomeLayout.removeView(mCameraPreview); // This is necessary.
        mCameraPreview = null;

        if (wakeLock != null) {
            wakeLock.release();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSoundPlayer != null) {
            mSoundPlayer.release();
            mSoundPlayer = null;
        }
        if (CGlobal.myEngine != null) {
            CGlobal.myEngine.endEngine();
            CGlobal.myEngine = null;
        }
        sensorManager.unregisterListener(this);
    }

    @Keep
    public void setAndshowPreviewSize() {
        Camera.Size previewSize = mCameraPreview.getPreviewSize();
    }

    @Keep
    long scanPhoneTime = 0;
    @Keep
    protected String lineNum = "";
    @Keep
    protected String phoneNum = "";

    @Override
    public void returnRecogedData(RecogResult result, Bitmap bmImage) {
        handlerRes(result, bmImage);
    }

    @Keep
    public void scrollToView(final int topMove){
        mScrollViewContent.post(new Runnable() {
            @Override
            public void run() {
                mScrollViewContent.scrollTo(0,topMove);
            }
        });
    }
    @Keep
    protected void handlerRes(RecogResult result, Bitmap bmImage) {
        if (!isAvailable()) return;
        CGlobal.g_RecogResult = result;
        if (isQrCodeOne) {
            if (result == null || result.m_lineNumber == null || result.m_lineNumber.length() < 8)
                return;
            lineNum = result.m_lineNumber;
            isQrCodeOne = false;
            scanPhoneTime = System.currentTimeMillis();
            restartScan();
        } else {
            phoneNum = CGlobal.MakePhoneNumberTypeString(result.m_szNumber);
            if (compareStrings(lineNum, phoneNum)) {
                restartScan();
                return;
            } else {
                if(!Tools.isPhone(phoneNum)){
                    restartScan();
                    return;
                }
                scrollToView(1000);
                if (vibrator != null) vibrator.vibrate(200L);
                isQrCodeOne = true;
                isbIsAvailable = false;
            }

        }
    }

    public static boolean compareStrings(String targetStr, String str) {
        if (targetStr.contains(str)) {
            return true;
        } else {
            return false;
        }
    }



    @Keep
    public void initScan() {
        lineNum = "";
        phoneNum = "";
        isbIsAvailable = true;
        isQrCodeOne = true;
        restartScan();
    }

    @Override
    public void recogedFailed() {
        if (isScanOutTime()) {
            outTimeWarning();
        }
    }

    @Override
    public void onClick(View v) {
        if (mCameraPreview != null) {
            mCameraPreview.autoCameraFocuse();
        }
    }

    @Keep
    private void restartScan() {
        if (m_scanHandler!=null) {
            isbIsAvailable = true;
            m_scanHandler.sendEmptyMessage(R.id.restart_preview);
        }
    }

    @Keep
    protected abstract void outTimeWarning();

    @Keep
    protected boolean isScanOutTime() {
        if (lastSuccessTime > 0 && (System.currentTimeMillis() - lastSuccessTime) > 1000 * 60 * 2) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isAvailable() {
        return isbIsAvailable;
    }

    @Override
    public void setIsAvailable(boolean isAvailable) {
        isbIsAvailable = isAvailable;
    }

    @Keep
    public boolean isQrCodeOne() {
        return isQrCodeOne;
    }

    @Keep
    public void setIsQrCodeOne(boolean isQrCodeOnes) {
        isQrCodeOne = isQrCodeOnes;
    }


    private long lastTime;

    private float lastX;
    private float lastY;
    private float lastZ;

    @Keep
    @Override
    public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            long currentTime = System.currentTimeMillis();
            long gabOfTime = (currentTime - lastTime);
            if (gabOfTime > 1000 && isAvailable() == true) {
                lastTime = currentTime;
                float x = event.values[0];
                float y = event.values[1];
                float z = event.values[2];


                float deltaX = Math.abs(lastX - x);
                float deltaY = Math.abs(lastY - y);
                float deltaZ = Math.abs(lastZ - z);


                //通过计算重力感应来激活自动对焦
                if ((deltaX > 0.2 || deltaY > 0.2 || deltaZ > 0.2)) {
                    if(isQrCodeOne()){
                        setIsAvailable(true);
                        restartScan();
                    }
                }
                lastX = x;
                lastY = y;
                lastZ = z;

            }
        }
    }

    @Keep
    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }
}